package org.xx.armory.swing.components;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xx.armory.swing.UIControllers;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.Color;
import java.awt.Component;

import static org.xx.armory.commons.Validators.notNull;
import static org.xx.armory.swing.components.FormatUtils.getCurrencyFormat;
import static org.xx.armory.swing.components.FormatUtils.getDateFormat;
import static org.xx.armory.swing.components.FormatUtils.getDateTimeFormat;
import static org.xx.armory.swing.components.FormatUtils.getFloatFormat;
import static org.xx.armory.swing.components.FormatUtils.getNumberFormat;
import static org.xx.armory.swing.components.FormatUtils.getNumberTextFormat;
import static org.xx.armory.swing.components.FormatUtils.getPercentFormat;

public class TypedTableCellRenderer
        extends DefaultTableCellRenderer
        implements TableCellRenderer {
    private final Logger logger = LoggerFactory.getLogger(TypedTableCellRenderer.class);

    private final TableCellRenderer parentRenderer;

    private TypedTableColumnType type;

    public TypedTableCellRenderer(
            TypedTableColumnType type
    ) {
        this(null, type);
    }

    public TypedTableCellRenderer(
            TableCellRenderer parentRenderer,
            TypedTableColumnType type
    ) {
        this.parentRenderer = parentRenderer;
        this.type = notNull(type, "type");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected,
            boolean hasFocus,
            int row,
            int column
    ) {
        final Component superResult;
        if (this.parentRenderer != null) {
            superResult = this.parentRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        } else {
            superResult = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }


        if (!(superResult instanceof JLabel)) {
            logger.warn("super result should be JLabel, but  {}", superResult);
            return superResult;
        }

        JLabel result = (JLabel) superResult;

        if (value == null) {
            result.setText("");
        } else {
            switch (type) {
                case TEXT:
                    // value可以是任意类型。
                    result.setHorizontalAlignment(JLabel.CENTER);
                    result.setText(value.toString());
                    break;
                case NUMBER:
                    // value必须是Number类型。
                    result.setHorizontalAlignment(JLabel.TRAILING);
                    result.setText(getNumberFormat().format(value));
                    break;
                case NUMBER_TEXT:
                    // value必须是Number类型。
                    result.setHorizontalAlignment(JLabel.TRAILING);
                    result.setText(getNumberTextFormat().format(value));
                    break;
                case FLOAT:
                    // value必须是Number类型。
                    result.setHorizontalAlignment(JLabel.TRAILING);
                    result.setText(getFloatFormat().format(value));
                    break;
                case PERCENT:
                    // value必须是BigDecimal类型。
                    result.setHorizontalAlignment(JLabel.TRAILING);
                    result.setText(getPercentFormat().format(value));
                    break;
                case CURRENCY:
                    // value必须是BigDecimal类型。
                    result.setHorizontalAlignment(JLabel.TRAILING);
                    result.setText(getCurrencyFormat().format(value));
                    break;
                case DATE:
                    // value必须是Date类型。
                    result.setHorizontalAlignment(JLabel.CENTER);
                    result.setText(getDateFormat().format(value));
                    break;
                case DATE_TIME:
                    // value必须是Date类型。
                    result.setHorizontalAlignment(JLabel.CENTER);
                    result.setText(getDateTimeFormat().format(value));
                    break;
                case IMAGE:
                    // value必须是Icon类型。
                    result.setHorizontalAlignment(JLabel.CENTER);
                    result.setText("");
                    result.setIcon((Icon) value);
                    break;
                case YES_OR_NO:
                case CHECK_BOX:
                    // value必须是Boolean或者Number或者String类型。
                    // CHECK_BOX 列应当是可以编辑的，如果不能编辑，那么看作YES_OR_NO列。
                    result.setHorizontalAlignment(JLabel.CENTER);
                    result.setText("");
                    if ((Boolean) value) {
                        // 表示YES的图片。
                        result.setIcon(new ImageIcon(UIControllers.STANDARD.getImage("yes-small")));
                    } else {
                        // 表示NO的图片。
                        result.setIcon(new ImageIcon(UIControllers.STANDARD.getImage("no-small")));
                    }
                    break;
            }
        }

        if (!isSelected) {
            final Color bgColor = UIManager.getColor("Table.background");
            if (row % 2 != 0) {
                final Color aColor = new Color(
                        (int) (bgColor.getRed() * .85),
                        (int) (bgColor.getGreen() * .95),
                        (int) (bgColor.getBlue() * .95),
                        bgColor.getAlpha()
                );
                result.setBackground(aColor);
            } else {
                result.setBackground(bgColor);
            }
        }

        return result;
    }
}
